<?php

namespace Yjius\aibigmodel\deepseek;

use Yjius\aibigmodel\AIBigModelBuilderInterface;
use Yjius\common\LoggerHelper;

class DeepSeek implements AIBigModelBuilderInterface
{
    //实例化代码
    static private $instance;

    private function __construct($params)
    {
        $this->chatUrl = $params['chat_url'] ?? "https://api.deepseek.com/chat/completions";
        $this->chatModel = $params['chat_model'] ?? "deepseek-chat";
        $this->apiKey = $params['api_key'] ?? "";
        if (empty($this->apiKey)) {
            throw new \Exception("DeepSeek:api_key不能为空");
        }
        $this->saveLog = $params['save_log'] ?? false;
        if ($this->saveLog) {
            $this->loggerInstance = LoggerHelper::init();
        }
    }

    /**
     * 处理单次聊天的结果
     *
     * 该方法旨在解析给定的JSON字符串，提取并返回其中的特定信息
     * 主要用于从API响应中提取聊天内容
     *
     * @param string $paramsStr JSON格式的字符串，包含聊天结果
     * @return string|null 返回提取的聊天内容文本，如果解析失败或数据不存在则返回null
     */
    public function chatOnceDealResult(string $paramsStr, array $customerParams)
    {
        try {
            // 将JSON字符串转换为关联数组
            $dataArr = json_decode($paramsStr, true);

            // 提取并返回聊天内容
            return $dataArr['choices'][0]['message']['content'] ?? "";
        } catch (\Exception $e) {
            // 直接返回null，不记录错误信息
            return null;
        }
    }

    /**
     * Purpose: 单次聊天返回
     * @param $content
     * @return bool|string
     * @throws \Exception
     * @date 2024/12/30 11:42
     */
    public function chatOnce(array $paramsArray, array $customerParams)
    {
        $data = [
            'messages' => [
                [
                    'content' => 'You are a helpful assistant.',
                    'role' => 'system'
                ],
                [
                    'content' => "Hi",
                    'role' => 'user'
                ]
            ],
            'model' => $this->chatModel,
            'frequency_penalty' => 0,
            'presence_penalty' => 0,
            'max_tokens' => 2048,
            'response_format' => [
                'type' => 'text'
            ],
            'stream' => false,
            'stream_options' => null,
            'temperature' => 1,
            'top_p' => 1,
            'tools' => null,
            'tool_choice' => 'none',
            'logprobs' => false,
            'top_logprobs' => null
        ];
        $data = array_merge($data, $paramsArray);
        $res = $this->curlRequest($data);
        if ($this->saveLog) {
            //问题结果日志记录
            $this->loggerInstance->write("deepseek_" . $this->apiKey . ".log", json_encode($data, JSON_UNESCAPED_UNICODE));
            $this->loggerInstance->write("deepseek_" . $this->apiKey . ".log", $res);
        }
        return $res;
    }

    private function __clone()
    {
    }

    //单例模式
    static public function getInstance($params)
    {
        if (!(self::$instance instanceof self)) {
            self::$instance = new self($params);
        }
        return self::$instance;
    }

    //发起CURL请求
    private function curlRequest($data = [])
    {
        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_URL => $this->chatUrl,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_HTTPHEADER => array(
                'Content-Type: application/json',
                'Accept: application/json',
                'Authorization: Bearer ' . $this->apiKey
            ),
        ));

        $response = curl_exec($curl);

        $errno = curl_errno($curl);       //curl错误码
        $error = curl_error($curl);       //curl错误信息


        if ($errno) {         //curl异常
            $curlError = json_encode(['curl_errno' => $errno, 'curl_error' => $error], JSON_UNESCAPED_UNICODE);
            throw new \Exception("curl异常：" . $curlError);
        }

        curl_close($curl);
        return $response;
    }

}